package com.unity.bh3.manager;

import com.unity.bh3.model.ChatMessage;
import com.unity.bh3.model.UserInfo;
import com.unity.bh3.service.UserService;
import com.unity.bh3.dto.UserInfoResponse;
import com.unity.bh3.netty.WebSocketMessage;
import io.netty.channel.Channel;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.util.concurrent.GlobalEventExecutor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.alibaba.fastjson2.JSON;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

@Component
public class ChatRoomManager {
    @Autowired
    private UserService userService;

    // 房间ID -> 该房间的所有连接
    private final Map<String, ChannelGroup> roomChannels = new ConcurrentHashMap<>();
    // 连接 -> 用户信息
    private final Map<Channel, UserInfo> channelUserMap = new ConcurrentHashMap<>();
    // 连接 -> 房间ID
    private final Map<Channel, String> channelRoomMap = new ConcurrentHashMap<>();
    
    public void joinRoom(String roomId, String userId, Channel channel) {
        // 从数据库获取用户信息
        UserInfoResponse userInfoResponse = userService.getUserInfo(Long.parseLong(userId));
        if (userInfoResponse == null) {
            WebSocketMessage errorMessage = WebSocketMessage.builder()
                    .type("ERROR")
                    .data("用户不存在")
                    .build();
            channel.writeAndFlush(new TextWebSocketFrame(JSON.toJSONString(errorMessage)));
            return;
        }

        // 创建用户信息对象
        UserInfo userInfo = new UserInfo(
            userId,
            userInfoResponse.getNickname(),
            "/images/avatars/" + userInfoResponse.getDisplayCharacterId() + ".png"
        );
        
        // 获取或创建房间的channel group
        roomChannels.computeIfAbsent(roomId, k -> new DefaultChannelGroup(GlobalEventExecutor.INSTANCE));
        
        // 如果用户已经在其他房间，先离开那个房间
        String currentRoomId = channelRoomMap.get(channel);
        if (currentRoomId != null && !currentRoomId.equals(roomId)) {
            leaveRoom(channel);
        }
        
        // 加入新房间
        ChannelGroup group = roomChannels.get(roomId);
        group.add(channel);
        channelUserMap.put(channel, userInfo);
        channelRoomMap.put(channel, roomId);
        
        // 发送房间信息给新加入的用户
        Map<String, Object> roomInfoData = new HashMap<>();
        roomInfoData.put("roomId", roomId);
        roomInfoData.put("userCount", group.size());
        List<Map<String, String>> users = new ArrayList<>();
        for (Channel ch : group) {
            if (ch != channel) {
                UserInfo user = channelUserMap.get(ch);
                if (user != null) {
                    Map<String, String> userMap = new HashMap<>();
                    userMap.put("userId", user.getUserId());
                    userMap.put("nickname", user.getNickname());
                    userMap.put("avatar", user.getAvatar());
                    users.add(userMap);
                }
            }
        }
        roomInfoData.put("users", users);
        
        WebSocketMessage roomInfoMessage = WebSocketMessage.builder()
                .type("ROOM_INFO")
                .data(roomInfoData)
                .build();
        channel.writeAndFlush(new TextWebSocketFrame(JSON.toJSONString(roomInfoMessage)));
        
        // 通知其他用户有新人加入
        Map<String, Object> joinData = new HashMap<>();
        joinData.put("roomId", roomId);
        joinData.put("userCount", group.size());
        Map<String, String> newUserInfo = new HashMap<>();
        newUserInfo.put("userId", userInfo.getUserId());
        newUserInfo.put("nickname", userInfo.getNickname());
        newUserInfo.put("avatar", userInfo.getAvatar());
        joinData.put("user", newUserInfo);
        
        WebSocketMessage joinMessage = WebSocketMessage.builder()
                .type("JOIN")
                .data(joinData)
                .build();
        group.forEach(ch -> {
            if (ch != channel) {
                ch.writeAndFlush(new TextWebSocketFrame(JSON.toJSONString(joinMessage)));
            }
        });
    }
    
    public void leaveRoom(Channel channel) {
        String roomId = channelRoomMap.get(channel);
        UserInfo userInfo = channelUserMap.get(channel);
        
        if (roomId != null && userInfo != null) {
            ChannelGroup group = roomChannels.get(roomId);
            if (group != null) {
                group.remove(channel);
                int newUserCount = group.size();
                
                // 如果房间空了，删除房间
                if (newUserCount == 0) {
                    roomChannels.remove(roomId);
                } else {
                    // 通知其他用户有人离开
                    Map<String, Object> leaveData = new HashMap<>();
                    leaveData.put("roomId", roomId);
                    leaveData.put("userCount", newUserCount);
                    Map<String, String> leftUserInfo = new HashMap<>();
                    leftUserInfo.put("userId", userInfo.getUserId());
                    leftUserInfo.put("nickname", userInfo.getNickname());
                    leftUserInfo.put("avatar", userInfo.getAvatar());
                    leaveData.put("user", leftUserInfo);
                    
                    WebSocketMessage leaveMessage = WebSocketMessage.builder()
                            .type("LEAVE")
                            .data(leaveData)
                            .build();
                    group.writeAndFlush(new TextWebSocketFrame(JSON.toJSONString(leaveMessage)));
                }
            }
        }
        
        channelRoomMap.remove(channel);
        channelUserMap.remove(channel);
    }
    
    public void sendChatMessage(Channel channel, String content) {
        String roomId = channelRoomMap.get(channel);
        UserInfo userInfo = channelUserMap.get(channel);
        
        if (roomId != null && userInfo != null) {
            // 从数据库获取最新的用户信息
            UserInfoResponse userInfoResponse = userService.getUserInfo(Long.parseLong(userInfo.getUserId()));
            if (userInfoResponse != null) {
                Map<String, Object> chatData = new HashMap<>();
                chatData.put("userId", userInfo.getUserId());
                chatData.put("nickname", userInfoResponse.getNickname());
                chatData.put("avatar", "/images/avatars/" + userInfoResponse.getDisplayCharacterId() + ".png");
                chatData.put("content", content);
                chatData.put("timestamp", System.currentTimeMillis());
                
                WebSocketMessage chatMessage = WebSocketMessage.builder()
                        .type("CHAT")
                        .data(chatData)
                        .build();
                
                ChannelGroup group = roomChannels.get(roomId);
                if (group != null) {
                    group.writeAndFlush(new TextWebSocketFrame(JSON.toJSONString(chatMessage)));
                }
            }
        }
    }
    
    public UserInfo getUserInfo(Channel channel) {
        return channelUserMap.get(channel);
    }
    
    public String getRoomId(Channel channel) {
        return channelRoomMap.get(channel);
    }
    
    public int getRoomUserCount(String roomId) {
        ChannelGroup group = roomChannels.get(roomId);
        return group != null ? group.size() : 0;
    }
    
    public boolean isRoomExist(String roomId) {
        return roomChannels.containsKey(roomId);
    }
} 